package assignmentonepenguins

import org.springframework.dao.DataIntegrityViolationException
import grails.plugins.springsecurity.Secured
import grails.plugins.springsecurity.SpringSecurityService
import com.security.User
import static grails.plugins.springsecurity.SpringSecurityService.*
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
import grails.converters.deep.JSON

class ListingController {

    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]
    def springSecurityService
    def listingService;

    def index() {
        redirect(action: "list", params: params)
    }

    def list() {
        params.max = Math.min(params.max ? params.int('max') : 5, 100)
        Date now = new Date()
        def query = Listing.where {endDate > now}
        def listingInstanceList1 = query.list(sort: 'dateCreated', order: "desc")
        listingInstanceList1 = query.list(params)
        [listingInstanceList: listingInstanceList1, listingInstanceTotal: Listing.count()]
    }

    @Secured(['ROLE_USER'])
    def create() {

        listingService.createListing(params);
    }

    def save() {
        def listingInstance = new Listing(params)
        listingInstance.setCreatedBy(request.getUserPrincipal().getName().toString())
        if (!listingInstance.save(flush: true)) {
            render(view: "create", model: [listingInstance: listingInstance])
            return
        }

        flash.message = message(code: 'default.created.message', args: [message(code: 'listing.label', default: 'Listing'), listingInstance.id])
        redirect(action: "show", id: listingInstance.id)
    }

    def show() {

        def listingInstance = Listing.get(params.id)
        if (listingService.isListingExpired(listingInstance)) {
            flash.message = "This listing has expired"
            return
        }
        else {
            if (!listingInstance) {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])
                redirect(action: "list")
                return
            }
            [listingInstance: listingInstance]
        }

    }

    @Secured(['ROLE_USER'])
    def edit() {
        def listingInstance = Listing.get(params.id)
        if (!listingInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])
            redirect(action: "list")
            return
        }

        [listingInstance: listingInstance]
    }

    @Secured(['ROLE_USER'])
    def update() {
        def listingInstance = Listing.get(params.id)
        if (!listingInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])
            redirect(action: "list")
            return
        }

        if (params.version) {
            def version = params.version.toLong()
            if (listingInstance.version > version) {
                listingInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
                        [message(code: 'listing.label', default: 'Listing')] as Object[],
                        "Another user has updated this Listing while you were editing")
                render(view: "edit", model: [listingInstance: listingInstance])
                return
            }
        }

        listingInstance.properties = params

        if (!listingInstance.save(flush: true)) {
            render(view: "edit", model: [listingInstance: listingInstance])
            return
        }

        flash.message = message(code: 'default.updated.message', args: [message(code: 'listing.label', default: 'Listing'), listingInstance.id])
        redirect(action: "show", id: listingInstance.id)
    }

    @Secured(['ROLE_USER'])
    def delete() {
        def listingInstance = Listing.get(params.id)
        if (!listingInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])
            redirect(action: "list")
            return
        }

        try {
            listingInstance.delete(flush: true)
            flash.message = message(code: 'default.deleted.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])
            redirect(action: "list")
        }
        catch (DataIntegrityViolationException e) {
            flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'listing.label', default: 'Listing'), params.id])
            redirect(action: "show", id: params.id)
        }
    }

    def myListings() {
        def userName = request.getUserPrincipal().getName().toString()
        def query = Listing.findAllByCreatedByLike(userName)
//        def query = Listing.findByCreatedBy(userName)
//        def listingInstanceList1 = query.asList(sort: 'dateCreated', order: "desc")
//        listingInstanceList1 = query.asList(params)
        [listingInstanceList: query.sort(), listingInstanceTotal: Listing.count()]

    }

    def addBid() {
        User currentUser = springSecurityService.currentUser
        Bidding bid = new Bidding()
        bid.amount = params.getDouble("amount")
        bid.bidder = Customer.findById(currentUser.id)
        bid.dateCreated = new Date() + 1
        bid.listing = Listing.findById(params.listingId)
        if (!bid.save(flush: true)) {
            flash.message = message(code: 'add.new.bidding.failure',)
        }
        else {
            flash.message = message(code: 'add.new.bidding.success',)
            bid.refresh()
        }

        [listingInstance: Listing.findById(params.listingId)]
        redirect(action: "show", id: params.listingId)
    }

    def getMinBid(long listingId) {
        Listing aListing = Listing.findById(listingId)
        double minBid = aListing.getBiddings().sort {x, y -> y.amount.compareTo(x.amount)}.get(0).amount + 0.5
        render minBid as JSON
    }

    def isListingExpired() {
        def id = params.id

        listingService.isListingExpired()
    }
}
